home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
utility
/
252
/
dskpcsrc
/
phoneboo.mod
< prev
next >
Wrap
Text File
|
1988-02-13
|
50KB
|
1,472 lines
IMPLEMENTATION MODULE PhoneBook;
(*$S-,$T- turn off stack and range checking *)
FROM SYSTEM IMPORT ADR, ADDRESS, TSIZE;
IMPORT M2Conversions;
IMPORT GEMDOS;
IMPORT GEMAESbase;
IMPORT AESApplications;
IMPORT AESEvents;
IMPORT AESForms;
IMPORT AESObjects;
IMPORT AESGraphics;
IMPORT Configuration;
IMPORT Text;
IMPORT Resource;
IMPORT Screen;
IMPORT Icon;
IMPORT Dialog;
IMPORT Window;
IMPORT File;
IMPORT Clock;
IMPORT Calendar;
IMPORT Disk;
CONST
LogOpenMsgLine1 = "[1][ The log file is not in | drive ";
PhoneOpenMsgLine1 = "[1][ The phonebook file is not in | drive ";
OpenMsgLine2 = ":. What would you | like to do?][Retry|Create|Cancel]";
PhoneExistsMsg = "[3][ The disk already contains | a phonebook file. ][ Cancel ]";
LogExistsMsg = "[3][ The disk already contains | a log File. ][ Cancel ]";
DiskFullMsg = "[3][ The disk is full. ][ Cancel ]";
CreateFailMsgLine1 = "[3][ Can't create the file. Make |";
CreateFailMsgLine2 = " sure that a DeskPak folder | is in drive ";
CreateFailMsgLine3 = ": and that the | disk is not write protected. ][Cancel]";
Null = 0;
NoSelectedEntries = 0;
CR = 15C;
Bell = 07C;
NumberSelectors = 13;
NumberEntries = 8;
TYPE
String1 = ARRAY [0..0] OF CHAR;
String3 = ARRAY [0..3] OF CHAR;
String10 = ARRAY [0..9] OF CHAR;
String35 = ARRAY [0..34] OF CHAR;
String3Ptr = POINTER TO String3;
String35Ptr = POINTER TO String35;
TYPE EntryInfo = RECORD
RecordHeader : File.RecordHeaderType;
Category : String1;
NameText : String35;
Number : String35;
ValidEntry : BOOLEAN;
RecordId : File.RecordIdType;
RateDayFirst : CARDINAL;
RateDayAdditional : CARDINAL;
RateEveningFirst : CARDINAL;
RateEveningAdditional : CARDINAL;
RateNightFirst : CARDINAL;
RateNightAdditional : CARDINAL;
END;
TYPE EntryInfoPtr = POINTER TO EntryInfo;
TYPE SelectorInfo = RECORD
Letter : String1;
ObjectIndex : INTEGER;
ObjectPtr : Icon.ObjectPtr;
END;
TYPE NameInfo = RECORD
Entry : EntryInfo;
ObjectIndex : INTEGER;
ObjectPtr : Icon.ObjectPtr;
END;
VAR
VirginTool : BOOLEAN;
WindowAllocated : BOOLEAN;
WindowInfo : Window.Information;
WindowResource : INTEGER;
Selector : ARRAY [1..NumberSelectors] OF SelectorInfo;
Category : CARDINAL;
Name : ARRAY [1..NumberEntries] OF NameInfo;
SelectedEntry : CARDINAL;
DialedEntry : CARDINAL;
DeletedEntry : CARDINAL;
PreviousTime : CARDINAL;
ElapsedHours : CARDINAL;
ElapsedMinutes : CARDINAL;
Cost : CARDINAL;
DisplayedTime : String10;
DisplayedCost : String10;
PhoneDrive : CHAR;
PhoneDriveNumber : CARDINAL;
LogDrive : CHAR;
LogDriveNumber : CARDINAL;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE OpenFile (
OpenLog : BOOLEAN;
VAR LogFileId : INTEGER;
VAR PhoneFileId : File.FileIdType ) : BOOLEAN;
CONST
ReadWrite = 2;
NormalFile = 0;
VAR
FileOpened : BOOLEAN;
FileId : INTEGER;
Success : BOOLEAN;
ErrorMsg : ARRAY [0..150] OF CHAR;
Choice : INTEGER;
BEGIN
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
FileOpened := FALSE;
LOOP
IF OpenLog THEN
Disk.CheckStatus ( LogDriveNumber );
GEMDOS.Open ( Configuration.LogFileName, ReadWrite, LogFileId );
FileOpened := (LogFileId >= GEMDOS.EOK);
ELSE
Disk.CheckStatus ( PhoneDriveNumber );
File.Open ( Configuration.PhoneFileName, GetKey, GetSubKey, PhoneFileId );
FileOpened := (File.Status = File.EOK);
END;
IF FileOpened THEN
EXIT;
ELSE
IF OpenLog THEN
ErrorMsg := LogOpenMsgLine1;
Success := Text.ConcatChar ( ErrorMsg, LogDrive, ErrorMsg );
ELSE
ErrorMsg := PhoneOpenMsgLine1;
Success := Text.ConcatChar ( ErrorMsg, PhoneDrive, ErrorMsg );
END;
Success := Text.ConcatString ( ErrorMsg, OpenMsgLine2, ErrorMsg );
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, ErrorMsg );
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
IF Choice = 1 THEN
(* Stay in loop and try again *)
ELSIF Choice = 2 THEN
(*--- Make sure that the file doesnt exist -------------*)
IF OpenLog THEN
Disk.CheckStatus ( LogDriveNumber );
GEMDOS.Open ( Configuration.LogFileName, ReadWrite, FileId );
FileOpened := (FileId >= GEMDOS.EOK);
IF FileOpened THEN
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, LogExistsMsg );
END;
ELSE
Disk.CheckStatus ( PhoneDriveNumber );
GEMDOS.Open ( Configuration.PhoneFileName, ReadWrite, FileId );
FileOpened := (FileId >= GEMDOS.EOK);
IF FileOpened THEN
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, PhoneExistsMsg );
END;
END;
IF FileOpened THEN
Success := GEMDOS.Close ( FileId );
FileOpened := FALSE;
ELSE (* NOT FileOpened *)
(*--- The file doesnt exist, so try to create it ----*)
IF OpenLog THEN
GEMDOS.Create ( Configuration.LogFileName, NormalFile, LogFileId );
FileOpened := (LogFileId >= GEMDOS.EOK);
ELSE
File.Create (
Configuration.PhoneFileName,
TSIZE (EntryInfo),
GetKey,
GetSubKey,
PhoneFileId );
FileOpened := (File.Status = File.EOK);
END;
IF NOT FileOpened THEN
ErrorMsg := CreateFailMsgLine1;
Success := Text.ConcatString (
ErrorMsg, CreateFailMsgLine2, ErrorMsg );
IF OpenLog THEN
Success := Text.ConcatChar (
ErrorMsg, LogDrive, ErrorMsg );
ELSE
Success := Text.ConcatChar (
ErrorMsg, PhoneDrive, ErrorMsg );
END;
Success := Text.ConcatString (
ErrorMsg, CreateFailMsgLine3, ErrorMsg );
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, ErrorMsg );
END;
END;
EXIT;
ELSE (* Choice = 3 *)
EXIT;
END;
END;
END; (* LOOP *)
RETURN (FileOpened);
END OpenFile;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE GetKey ( Data : ADDRESS;
VAR Key : ARRAY OF CHAR );
VAR Entry : EntryInfoPtr;
BEGIN
Entry := EntryInfoPtr (Data);
Text.Assign ( Entry^.Category, Key );
END GetKey;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE GetSubKey ( Data : ADDRESS;
VAR SubKey : ARRAY OF CHAR );
VAR Entry : EntryInfoPtr;
BEGIN
Entry := EntryInfoPtr (Data);
Text.Assign ( Entry^.NameText, SubKey );
END GetSubKey;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE ReadPhoneBook (
ValidId : BOOLEAN;
EntryId : File.RecordIdType;
Redraw : BOOLEAN );
CONST
PhoneBookFile = FALSE;
EmptyLine = "___________________________________";
VAR
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
NextEntry : EntryInfo;
FoundRecord : BOOLEAN;
FileOpened : BOOLEAN;
Index : CARDINAL;
WorkBuffer : EntryInfo;
RecordId : File.RecordIdType;
Success : BOOLEAN;
FirstLetter : CHAR;
SecondLetter : CHAR;
BEGIN
FoundRecord := FALSE;
(*--- Turn off the current selector -----------------------------*)
Selector[Category].ObjectPtr^.State :=
Selector[Category].ObjectPtr^.State - {Icon.Selected};
IF Redraw THEN
Icon.Display (
Resource.D6PHONE,
Selector[Category].ObjectIndex,
WindowInfo.Borders );
END;
(*--- Open the phonebook file -----------------------------------*)
IF ValidId THEN
FileOpened := OpenFile ( PhoneBookFile, LogFileId, PhoneFileId );
ELSE
FileOpened := FALSE;
END;
IF FileOpened THEN
(*--- Get the first record -----------------------------------*)
IF EntryId = Null THEN (* Start at the beginning of the file *)
File.Read ( PhoneFileId, ADR (NextEntry), RecordId );
ELSE
File.Seek ( PhoneFileId, EntryId, ADR (NextEntry) );
RecordId := EntryId;
END;
IF File.Status = File.EOK THEN
(*--- Determine the current category ----------------------*)
FoundRecord := TRUE;
Category := 1;
LOOP
FirstLetter := Selector[Category].Letter[0];
SecondLetter := CHR (ORD (FirstLetter) + 1);
IF (NextEntry.Category[0] = FirstLetter) OR
(NextEntry.Category[0] = SecondLetter) THEN
EXIT;
END;
INC (Category);
IF Category > NumberSelectors THEN
DEC (Category);
EXIT;
END;
END (* LOOP *);
END;
END;
(*--- Read in the remaining entries -----------------------------*)
Index := 1;
LOOP
IF FileOpened AND
(File.Status = File.EOK) AND
((NextEntry.Category[0] = FirstLetter) OR
(NextEntry.Category[0] = SecondLetter)) THEN
Name[Index].Entry := NextEntry;
Name[Index].Entry.ValidEntry := TRUE;
Name[Index].Entry.RecordId := RecordId;
ELSE
Name[Index].Entry.ValidEntry := FALSE;
Name[Index].Entry.NameText := EmptyLine;
END;
INC ( Index );
IF Index <= NumberEntries THEN
IF FileOpened THEN (* Get next record from file *)
File.Read ( PhoneFileId, ADR (NextEntry), RecordId );
END;
ELSE
EXIT;
END;
END; (* LOOP *)
(*--- Close the phonebook file ----------------------------------*)
IF FileOpened THEN
File.Close ( PhoneFileId );
END;
(*--- Highlight the current selector ----------------------------*)
IF FoundRecord THEN
Selector[Category].ObjectPtr^.State :=
Selector[Category].ObjectPtr^.State + {Icon.Selected};
END;
IF Redraw THEN
Icon.Display (
Resource.D6PHONE,
Selector[Category].ObjectIndex,
WindowInfo.Borders );
Icon.Display (
Resource.D6PHONE,
Resource.D6NUMBRS,
WindowInfo.Borders );
END;
END ReadPhoneBook;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE EditEntry ( VAR Item : EntryInfo );
TYPE TedInfoPtrType = POINTER TO Icon.Tedinfo;
VAR
ObjectPtr : Icon.ObjectPtr;
TedInfoPtr : TedInfoPtrType;
NamePtr : String35Ptr;
NumberPtr : String35Ptr;
RateDayFirst : String3Ptr;
RateDayAdditional : String3Ptr;
RateEveningFirst : String3Ptr;
RateEveningAdditional : String3Ptr;
RateNightFirst : String3Ptr;
RateNightAdditional : String3Ptr;
Success : BOOLEAN;
CaseConversion : CARDINAL;
BEGIN
(*--- Save the addresses of the various dialog box objects -------*)
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7NAME );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
NamePtr := String35Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7NUMBER );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
NumberPtr := String35Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7FDAY );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateDayFirst := String3Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7EDAY );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateDayAdditional := String3Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7FEVEN );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateEveningFirst := String3Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7EEVEN );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateEveningAdditional := String3Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7FNIGHT );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateNightFirst := String3Ptr (TedInfoPtr^.Text);
ObjectPtr := Icon.GetAddress ( Resource.D7PHINFO, Resource.D7ENIGHT );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
RateNightAdditional := String3Ptr (TedInfoPtr^.Text);
(*--- Initialize the dialog box objects --------------------------*)
Text.Assign ( Item.NameText, NamePtr^ );
Text.Assign ( Item.Number, NumberPtr^ );
M2Conversions.ConvertCardinal (
Item.RateDayFirst, 3, RateDayFirst^ );
M2Conversions.ConvertCardinal (
Item.RateDayAdditional, 3, RateDayAdditional^ );
M2Conversions.ConvertCardinal (
Item.RateEveningFirst, 3, RateEveningFirst^ );
M2Conversions.ConvertCardinal (
Item.RateEveningAdditional, 3, RateEveningAdditional^ );
M2Conversions.ConvertCardinal (
Item.RateNightFirst, 3, RateNightFirst^ );
M2Conversions.ConvertCardinal (
Item.RateNightAdditional, 3, RateNightAdditional^ );
(*--- Invoke the dialog ------------------------------------------*)
Item.ValidEntry := (Dialog.Display (
Resource.D7PHINFO, Screen.Center, Resource.D7NAME ) =
Resource.D7OK);
(*--- Save the results -------------------------------------------*)
Text.Assign ( NamePtr^, Item.NameText );
Item.Category[0] := Item.NameText[0];
IF Item.Category[0] > 'Z' THEN
CaseConversion := ORD ('a') - ORD ('A');
Item.Category[0] := CHR (ORD (Item.Category[0]) - CaseConversion);
END;
Text.Assign ( NumberPtr^, Item.Number );
M2Conversions.ConvertToCardinal (
RateDayFirst^, Success, Item.RateDayFirst );
M2Conversions.ConvertToCardinal (
RateDayAdditional^, Success, Item.RateDayAdditional );
M2Conversions.ConvertToCardinal (
RateEveningFirst^, Success, Item.RateEveningFirst );
M2Conversions.ConvertToCardinal (
RateEveningAdditional^, Success, Item.RateEveningAdditional );
M2Conversions.ConvertToCardinal (
RateNightFirst^, Success, Item.RateNightFirst );
M2Conversions.ConvertToCardinal (
RateNightAdditional^, Success, Item.RateNightAdditional );
END EditEntry;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE EnableDialDelete;
VAR ObjectPtr : Icon.ObjectPtr;
BEGIN
ObjectPtr := Icon.GetAddress ( Resource.D6PHONE, Resource.D6DIAL );
ObjectPtr^.State := ObjectPtr^.State - {Icon.Disabled};
Icon.Display ( Resource.D6PHONE, Resource.D6DIAL, WindowInfo.Borders );
ObjectPtr := Icon.GetAddress ( Resource.D6PHONE, Resource.D6DELETE );
ObjectPtr^.State := ObjectPtr^.State - {Icon.Disabled};
Icon.Display ( Resource.D6PHONE, Resource.D6DELETE, WindowInfo.Borders );
END EnableDialDelete;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE DisableDialDelete;
VAR ObjectPtr : Icon.ObjectPtr;
BEGIN
ObjectPtr := Icon.GetAddress ( Resource.D6PHONE, Resource.D6DIAL );
ObjectPtr^.State := ObjectPtr^.State + {Icon.Disabled};
Icon.Display ( Resource.D6PHONE, Resource.D6DIAL, WindowInfo.Borders );
ObjectPtr := Icon.GetAddress ( Resource.D6PHONE, Resource.D6DELETE );
ObjectPtr^.State := ObjectPtr^.State + {Icon.Disabled};
Icon.Display ( Resource.D6PHONE, Resource.D6DELETE, WindowInfo.Borders );
END DisableDialDelete;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE DeselectEntries ();
VAR ObjectPtr : Icon.ObjectPtr;
BEGIN
IF SelectedEntry = NoSelectedEntries THEN
; (* Do nothing, since nothing is selected *)
ELSE
Name[SelectedEntry].ObjectPtr^.State :=
Name[SelectedEntry].ObjectPtr^.State - {Icon.Selected};
Icon.Display (
Resource.D6PHONE,
Name[SelectedEntry].ObjectIndex,
WindowInfo.Borders );
DisableDialDelete;
SelectedEntry := NoSelectedEntries;
END;
END DeselectEntries;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE MinutesSinceLastMark () : CARDINAL;
CONST MinutesPerDay = 1440;
VAR
Time : CARDINAL;
Minutes : CARDINAL;
Difference : CARDINAL;
BEGIN
GEMDOS.GetTime ( Time );
Minutes := (Time DIV 2048) * 60 + ((Time MOD 2048) DIV 32);
IF Minutes >= PreviousTime THEN
Difference := Minutes - PreviousTime;
ELSE (* Minutes < PreviousTime *)
Difference := MinutesPerDay - PreviousTime + Minutes;
END;
PreviousTime := Minutes;
RETURN (Difference);
END MinutesSinceLastMark;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE UpdateTime;
VAR
Buffer : String10;
Success : BOOLEAN;
BEGIN
ElapsedMinutes := ElapsedMinutes + MinutesSinceLastMark ();
IF ElapsedMinutes > 59 THEN
INC (ElapsedHours, (ElapsedMinutes DIV 60));
ElapsedMinutes := ElapsedMinutes MOD 60;
END;
M2Conversions.ConvertCardinal ( ElapsedHours, 2, DisplayedTime );
DisplayedTime[2] := ':';
DisplayedTime[3] := CHR (0);
M2Conversions.ConvertCardinal ( ElapsedMinutes, 2, Buffer );
IF Buffer[0] = ' ' THEN
Buffer[0] := '0';
END;
Success := Text.ConcatString ( DisplayedTime, Buffer, DisplayedTime );
END UpdateTime;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE UpdateCost;
VAR
RateFirst : CARDINAL;
RateAddt : CARDINAL;
Ticks : CARDINAL;
Buffer : String10;
Success : BOOLEAN;
BEGIN
IF Calendar.DayIsSaturday () OR
(Calendar.DayIsSunday () AND (NOT Clock.EveningPeriod ())) OR
Clock.NightPeriod () THEN
RateFirst := Name[DialedEntry].Entry.RateNightFirst;
RateAddt := Name[DialedEntry].Entry.RateNightAdditional;
ELSIF Clock.EveningPeriod () THEN
RateFirst := Name[DialedEntry].Entry.RateEveningFirst;
RateAddt := Name[DialedEntry].Entry.RateEveningAdditional;
ELSE (* It must be during the day *)
RateFirst := Name[DialedEntry].Entry.RateDayFirst;
RateAddt := Name[DialedEntry].Entry.RateDayAdditional;
END;
Ticks := (ElapsedHours * 60) + ElapsedMinutes;
IF Ticks < 1 THEN
Cost := 0;
ELSIF Ticks = 1 THEN
Cost := RateFirst;
ELSE (* Ticks > 1 *)
Cost := RateFirst + (RateAddt * (Ticks - 1));
END;
DisplayedCost := "$";
M2Conversions.ConvertCardinal ( (Cost DIV 100), 2, Buffer );
Success := Text.ConcatString ( DisplayedCost, Buffer, DisplayedCost );
DisplayedCost[3] := '.';
DisplayedCost[4] := CHR (0);
M2Conversions.ConvertCardinal ( (Cost MOD 100), 2, Buffer );
IF Buffer[0] = ' ' THEN
Buffer[0] := '0';
END;
Success := Text.ConcatString ( DisplayedCost, Buffer, DisplayedCost );
END UpdateCost;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE HangUp;
VAR
ObjectPtr : Icon.ObjectPtr;
TextPtr : String35Ptr;
BEGIN
(*--- Restore the components associated with Dialing -------------*)
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8DIAL );
ObjectPtr^.Flags := ObjectPtr^.Flags - {Icon.HideTree};
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8COST );
ObjectPtr^.Flags := ObjectPtr^.Flags - {Icon.HideTree};
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8MSG );
TextPtr := String35Ptr (ObjectPtr^.Spec);
TextPtr^ := "Dialing ...";
(*--- Open the phone directory window ----------------------------*)
Close; (* Close the time monitor window *)
WindowResource := Resource.D6PHONE;
Open;
END HangUp;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE InsertEntry ( Item : EntryInfo );
CONST
PhoneBookFile = FALSE;
ValidId = TRUE;
VAR
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
WorkBuffer : EntryInfo;
RecordId : File.RecordIdType;
InsertOK : BOOLEAN;
FoundKey : BOOLEAN;
KeyId : File.RecordIdType;
FoundRecord : BOOLEAN;
BEGIN
IF OpenFile ( PhoneBookFile, LogFileId, PhoneFileId ) THEN
File.InsertRecord (
PhoneFileId,
Item.Category,
Item.NameText,
ADR (Item),
ADR (WorkBuffer),
RecordId );
InsertOK := (File.Status = File.EOK);
File.Close ( PhoneFileId );
IF InsertOK AND OpenFile ( PhoneBookFile, LogFileId, PhoneFileId ) THEN
File.Find (
PhoneFileId,
Item.Category,
"",
ADR (WorkBuffer),
FoundKey,
KeyId,
FoundRecord,
RecordId );
File.Close ( PhoneFileId );
ReadPhoneBook ( FoundKey, KeyId, TRUE );
END;
END;
END InsertEntry;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE ProcessName ( EntryIndex : CARDINAL;
Clicks : INTEGER );
CONST PhoneBookFile = FALSE;
VAR
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
ObjectPtr : Icon.ObjectPtr;
Item : EntryInfo;
WorkBuffer : EntryInfo;
BEGIN
DeselectEntries;
IF Name[EntryIndex].Entry.ValidEntry THEN
IF Clicks = 1 THEN
(*--- The user single clicked, so select the entry ---------*)
Name[EntryIndex].ObjectPtr^.State :=
Name[EntryIndex].ObjectPtr^.State + {Icon.Selected};
Icon.Display (
Resource.D6PHONE,
Name[EntryIndex].ObjectIndex,
WindowInfo.Borders );
SelectedEntry := EntryIndex;
EnableDialDelete;
ELSE
(*--- The user double clicked, so edit the entry -----------*)
Item := Name[EntryIndex].Entry;
EditEntry ( Item );
IF Item.ValidEntry THEN
(* TBD - May want to see if the key has been modified. *)
(* If not, simply update the information by using *)
(* File.Write. If the keys are not the same, the *)
(* record must be deleted and reinserted as usual. *)
(*--- Save the new information on disk ------------------*)
IF OpenFile ( PhoneBookFile, LogFileId, PhoneFileId ) THEN
File.DeleteRecord (
PhoneFileId,
Name[EntryIndex].Entry.RecordId,
ADR (WorkBuffer) );
File.Close ( PhoneFileId );
InsertEntry ( Item );
END;
END;
END;
ELSE
GEMDOS.ConOut ( Bell );
END;
END ProcessName;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE TimeCall;
VAR ObjectPtr : Icon.ObjectPtr;
BEGIN
Close; (* Close the phone directory window *)
(*--- Hide the components associated with dialing ---------------*)
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8DIAL );
ObjectPtr^.Flags := ObjectPtr^.Flags + {Icon.HideTree};
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8COST );
ObjectPtr^.Flags := ObjectPtr^.Flags + {Icon.HideTree};
(*--- Start timing the phone call -------------------------------*)
ElapsedMinutes := MinutesSinceLastMark ();
ElapsedMinutes := 0; (* Ignore the previous call *)
ElapsedHours := 0;
DisplayedTime := " 0:00";
WindowResource := Resource.D8PHTIME;
Open; (* Open the time monitor window *)
END TimeCall;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE ModemOut ( VAR String : ARRAY OF CHAR ) : BOOLEAN;
VAR
Index : CARDINAL;
Ch : CHAR;
BEGIN
Index := 0;
LOOP
(*--- Clear out any characters from the input stream ----------*)
WHILE (GEMDOS.AuxIS ()) DO
GEMDOS.AuxIn ( Ch );
END;
(*--- Send the character to the modem ---*)
IF NOT GEMDOS.AuxOS () THEN
(*--- The RS-232 port is not ready, so wait 3 seconds ------*)
AESEvents.EventTimer ( 3000, 0 );
IF NOT GEMDOS.AuxOS () THEN
(*--- Still not ready, so the modem must be off ---------*)
RETURN (FALSE);
END;
END;
IF (Index > HIGH (String)) OR (String[Index] = CHR (0)) THEN
EXIT;
END;
GEMDOS.AuxOut ( String[Index] );
INC (Index);
END (* LOOP *);
RETURN (TRUE);
END ModemOut;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE Dial;
TYPE TedInfoPtrType = POINTER TO Icon.Tedinfo;
VAR
ObjectPtr : Icon.ObjectPtr;
TedInfoPtr : TedInfoPtrType;
NumberPtr : String35Ptr;
MsgPtr : String35Ptr;
NumberLength : CARDINAL;
Count : CARDINAL;
Success : BOOLEAN;
Ch : CHAR;
ModemOk : BOOLEAN;
BEGIN
Close; (* Close the directory window *)
(*--- Clear the "number dialed" field ----------------------------*)
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8NUMBER );
TedInfoPtr := TedInfoPtrType (ObjectPtr^.Spec);
NumberPtr := String35Ptr (TedInfoPtr^.Text);
Text.Assign ( Name[DialedEntry].Entry.Number, NumberPtr^ );
(*--- Start timing the phone call --------------------------------*)
ElapsedMinutes := MinutesSinceLastMark ();
ElapsedMinutes := 0; (* Ignore the previous call *)
ElapsedHours := 0;
DisplayedTime := " 0:00";
DisplayedCost := "$ 0.00";
WindowResource := Resource.D8PHTIME;
Open; (* Open the time monitor window *)
Window.Redraw ( WindowInfo.Id, WindowInfo.Borders );
(*--- Dial the number through the modem --------------------------*)
ModemOk := ModemOut ( Configuration.ModemDialPrefix );
IF ModemOk THEN
ModemOk := ModemOut ( Name[DialedEntry].Entry.Number );
END;
IF ModemOk THEN
ModemOk := ModemOut ( Configuration.ModemDialSuffix );
END;
IF ModemOk THEN
GEMDOS.AuxOut ( CR );
END;
(*--- Clear out any characters from the input stream -------------*)
WHILE (GEMDOS.AuxIS ()) DO
GEMDOS.AuxIn ( Ch );
END;
(*--- Inform the user that the number has been dialed ------------*)
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8MSG );
MsgPtr := String35Ptr (ObjectPtr^.Spec);
MsgPtr^ := " Dialed :";
END Dial;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE AddEntry;
VAR
NewEntry : EntryInfo;
Choice : INTEGER;
BEGIN
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
Disk.CheckStatus ( PhoneDriveNumber );
IF Disk.SpaceAvailable ( PhoneDriveNumber, LONGCARD (TSIZE (EntryInfo)) ) THEN
NewEntry.NameText := CHR (0);
NewEntry.Number := CHR (0);
NewEntry.RateDayFirst := 0;
NewEntry.RateDayAdditional := 0;
NewEntry.RateEveningFirst := 0;
NewEntry.RateEveningAdditional := 0;
NewEntry.RateNightFirst := 0;
NewEntry.RateNightAdditional := 0;
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
EditEntry ( NewEntry );
IF NewEntry.ValidEntry THEN
InsertEntry ( NewEntry );
END;
ELSE
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, DiskFullMsg );
END;
END AddEntry;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE DeleteEntry;
CONST
PhoneBookFile = FALSE;
ValidId = TRUE;
VAR
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
TopRecordId : File.RecordIdType;
WorkBuffer : EntryInfo;
BEGIN
IF OpenFile ( PhoneBookFile, LogFileId, PhoneFileId ) THEN
(*--- Get the id of the record that will fill the slot --------*)
(*--- after the selected record has been deleted. --------*)
IF DeletedEntry = 1 THEN
WITH Name[1].Entry.RecordHeader DO
IF NextRecordId <> Null THEN
TopRecordId := NextRecordId;
ELSIF PrevRecordId <> Null THEN
TopRecordId := PrevRecordId;
ELSE
TopRecordId := Null;
END;
END;
ELSE
TopRecordId := Name[1].Entry.RecordId;
END;
(*--- Delete the selected record ------------------------------*)
File.DeleteRecord (
PhoneFileId,
Name[DeletedEntry].Entry.RecordId,
ADR (WorkBuffer) );
File.Close ( PhoneFileId );
(*--- Redisplay the rest of the phone book --------------------*)
ReadPhoneBook ( (TopRecordId <> Null), TopRecordId, TRUE );
END;
END DeleteEntry;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE SendName ( Name : ADDRESS );
VAR MsgBuffer : ARRAY [0..7] OF INTEGER;
BEGIN
MsgBuffer[0] := Resource.CallBack;
MsgBuffer[1] := Resource.ApplicationId;
MsgBuffer[2] := 0;
MsgBuffer[3] := INTEGER (Name DIV 10000H);
MsgBuffer[4] := INTEGER (Name MOD 10000H);
AESApplications.ApplWrite (
Resource.ApplicationId, SIZE (MsgBuffer), ADR (MsgBuffer) );
END SendName;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE UpdateLog (
AddName : BOOLEAN;
VAR Name : ARRAY OF CHAR );
CONST
LogFile = TRUE;
UseFormat = TRUE;
CR = 015C;
LF = 012C;
VAR
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
Success : BOOLEAN;
Position : LONGCARD;
Time : CARDINAL;
Date : CARDINAL;
Count : LONGCARD;
TempBuffer : Text.String80;
Buffer : Text.String80;
Choice : INTEGER;
BEGIN
AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
Buffer[0] := CR;
Buffer[1] := CHR (0);
Success := Text.ConcatChar ( Buffer, LF, Buffer );
IF AddName THEN
GEMDOS.GetDate ( Date );
Clock.DecodeDate ( Date, UseFormat, TempBuffer );
Success := Text.ConcatString ( Buffer, TempBuffer, Buffer );
Success := Text.ConcatChar ( Buffer, ' ', Buffer );
GEMDOS.GetTime ( Time );
Clock.DecodeTime ( Time, UseFormat, TempBuffer );
Success := Text.ConcatString ( Buffer, TempBuffer, Buffer );
Success := Text.ConcatString ( Buffer, ": Called ", Buffer );
Success := Text.ConcatString ( Buffer, Name, Buffer );
ELSE
Buffer := ", Length of Call =";
Success := Text.ConcatString ( Buffer, DisplayedTime, Buffer );
IF Cost > 0 THEN
Success := Text.ConcatString ( Buffer, ", Cost = ", Buffer );
Success := Text.ConcatString ( Buffer, DisplayedCost, Buffer );
END;
END;
Count := LONGCARD (Text.Length ( Buffer ));
IF Disk.SpaceAvailable ( LogDriveNumber, Count ) THEN
IF OpenFile ( LogFile, LogFileId, PhoneFileId ) THEN
GEMDOS.Seek ( 0, LogFileId, GEMDOS.end, Position );
GEMDOS.Write ( LogFileId, Count, ADR (Buffer) );
Success := GEMDOS.Close ( LogFileId );
END;
ELSE
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
Choice := AESForms.FormAlert ( 1, DiskFullMsg );
END;
END UpdateLog;
(************************** LOCAL ROUTINE ***************************)
PROCEDURE PhoneBookDraw ( Region : Screen.Box );
BEGIN
; (* Already drawn by the window manager *)
END PhoneBookDraw;
(********************************************************************)
PROCEDURE Initialize ();
TYPE TedInfoPtrType = POINTER TO Icon.Tedinfo;
VAR
ObjectPtr : Icon.ObjectPtr;
Index : CARDINAL;
TedInfoPtr : TedInfoPtrType;
Ch : CHAR;
BEGIN
LogDrive := Configuration.LogFileName[0];
LogDriveNumber := ORD (LogDrive) - ORD ('A') + 1;
PhoneDrive := Configuration.PhoneFileName[0];
PhoneDriveNumber := ORD (PhoneDrive) - ORD ('A') + 1;
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8TIME );
ObjectPtr^.Spec := ADR ( DisplayedTime );
ObjectPtr := Icon.GetAddress ( Resource.D8PHTIME, Resource.D8AMOUNT );
ObjectPtr^.Spec := ADR ( DisplayedCost );
Name[1].ObjectIndex := Resource.D6NAME1;
Name[2].ObjectIndex := Resource.D6NAME2;
Name[3].ObjectIndex := Resource.D6NAME3;
Name[4].ObjectIndex := Resource.D6NAME4;
Name[5].ObjectIndex := Resource.D6NAME5;
Name[6].ObjectIndex := Resource.D6NAME6;
Name[7].ObjectIndex := Resource.D6NAME7;
Name[8].ObjectIndex := Resource.D6NAME8;
FOR Index := 1 TO 8 DO
Name[Index].ObjectPtr := Icon.GetAddress (
Resource.D6PHONE, Name[Index].ObjectIndex );
TedInfoPtr := TedInfoPtrType (Name[Index].ObjectPtr^.Spec);
TedInfoPtr^.Text := ADR (Name[Index].Entry.NameText);
END;
Selector[1].ObjectIndex := Resource.D6AB;
Selector[1].Letter := 'A';
Selector[2].ObjectIndex := Resource.D6CD;
Selector[2].Letter := 'C';
Selector[3].ObjectIndex := Resource.D6EF;
Selector[3].Letter := 'E';
Selector[4].ObjectIndex := Resource.D6GH;
Selector[4].Letter := 'G';
Selector[5].ObjectIndex := Resource.D6IJ;
Selector[5].Letter := 'I';
Selector[6].ObjectIndex := Resource.D6KL;
Selector[6].Letter := 'K';
Selector[7].ObjectIndex := Resource.D6MN;
Selector[7].Letter := 'M';
Selector[8].ObjectIndex := Resource.D6OP;
Selector[8].Letter := 'O';
Selector[9].ObjectIndex := Resource.D6QR;
Selector[9].Letter := 'Q';
Selector[10].ObjectIndex := Resource.D6ST;
Selector[10].Letter := 'S';
Selector[11].ObjectIndex := Resource.D6UV;
Selector[11].Letter := 'U';
Selector[12].ObjectIndex := Resource.D6WX;
Selector[12].Letter := 'W';
Selector[13].ObjectIndex := Resource.D6YZ;
Selector[13].Letter := 'Y';
FOR Category := 1 TO 13 DO
Selector[Category].ObjectPtr := Icon.GetAddress (
Resource.D6PHONE, Selector[Category].ObjectIndex );
END;
Category := 1;
WHILE (GEMDOS.AuxIS ()) DO
GEMDOS.AuxIn ( Ch );
END;
END Initialize;
(********************************************************************)
PROCEDURE OwnsWindow ( WindowId : INTEGER ) : BOOLEAN;
BEGIN
IF WindowAllocated THEN
RETURN (WindowId = WindowInfo.Id);
ELSE
RETURN (FALSE);
END;
END OwnsWindow;
(********************************************************************)
PROCEDURE Open;
CONST
FirstName = Null;
ValidId = TRUE;
VAR
WindowRegion : Screen.Box;
Components : INTEGER;
VirtualRegionSize : Window.Area;
BEGIN
IF WindowAllocated THEN
Window.Top ( WindowInfo.Id );
ELSE
Icon.GetRegion ( WindowResource, 0, WindowRegion );
WindowRegion.Origin.X :=
Screen.Center.Origin.X - (WindowRegion.Size.Width DIV 2);
WindowRegion.Origin.Y :=
Screen.Center.Origin.Y - (WindowRegion.Size.Height DIV 2);
VirtualRegionSize.Width :=
Window.Pixel (WindowRegion.Size.Width);
VirtualRegionSize.Height :=
Window.Pixel (WindowRegion.Size.Height) * 26;
IF WindowResource = Resource.D6PHONE THEN
Components :=
GEMAESbase.Name +
GEMAESbase.Closer +
GEMAESbase.Mover +
GEMAESbase.UpArrow +
GEMAESbase.DownArrow;
ELSE
Components :=
GEMAESbase.Name +
GEMAESbase.Closer +
GEMAESbase.Mover;
END;
IF Window.Open (
Screen.Center,
Window.InformationPtr (ADR (WindowInfo)),
" Phone Book ",
"", (* No information line *)
WindowRegion,
VirtualRegionSize,
Components,
0, 1, (* White Background *)
WindowResource,
PhoneBookDraw ) THEN
WindowAllocated := TRUE;
IF VirginTool THEN
ReadPhoneBook ( ValidId, FirstName, FALSE );
VirginTool := FALSE;
END;
ELSE
Window.Unavailable;
WindowAllocated := FALSE;
END;
END;
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
END Open;
(********************************************************************)
PROCEDURE Close;
BEGIN
IF WindowAllocated THEN
IF WindowResource = Resource.D6PHONE THEN
DeselectEntries;
END;
Window.Close ( WindowInfo.Id, Screen.Center );
WindowAllocated := FALSE;
END;
END Close;
(********************************************************************)
PROCEDURE ProcessMessageEvent ( VAR MsgBuffer : ARRAY OF INTEGER );
CONST
PhoneBookFile = FALSE;
RowUp = 2;
RowDown = 3;
ValidId = TRUE;
VAR RecordId : File.RecordIdType;
BEGIN
IF MsgBuffer[0] = GEMAESbase.AccessoryClose THEN
IF WindowAllocated THEN
DeselectEntries;
Window.Close ( 0, Screen.Center );
WindowAllocated := FALSE;
END;
ELSIF MsgBuffer[0] = GEMAESbase.WindowArrowed THEN
IF Name[1].Entry.ValidEntry THEN
IF MsgBuffer[4] = RowUp THEN
RecordId := Name[1].Entry.RecordHeader.PrevRecordId;
ELSE (* MsgBuffer[4] = RowDown *)
RecordId := Name[1].Entry.RecordHeader.NextRecordId;
END;
IF RecordId = Null THEN
GEMDOS.ConOut ( Bell );
ELSE
ReadPhoneBook ( ValidId, RecordId, TRUE );
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
END;
ELSE
GEMDOS.ConOut ( Bell );
END;
ELSIF MsgBuffer[0] = Resource.MinuteChanged THEN
IF WindowResource = Resource.D6PHONE THEN
; (* Ignore the time update *)
ELSE
UpdateTime;
IF DialedEntry <> Null THEN
UpdateCost;
END;
IF WindowAllocated THEN
Window.Redraw ( WindowInfo.Id, WindowInfo.Borders );
END;
END;
ELSE
GEMDOS.ConOut ( Bell );
END;
END ProcessMessageEvent;
(********************************************************************)
PROCEDURE ProcessButtonEvent ( MouseButton : INTEGER;
ModifierKey : INTEGER;
Clicks : INTEGER );
TYPE TedInfoPtrType = POINTER TO Icon.Tedinfo;
CONST
PhoneBookFile = FALSE;
AddName = TRUE;
AddTime = FALSE;
VAR
MouseLocation : Screen.PixelCoordinate;
MouseState : INTEGER;
KeyboardState : INTEGER;
Button : CARDINAL;
FoundButton : BOOLEAN;
Object : INTEGER;
ObjectPtr : Icon.ObjectPtr;
LogFileId : INTEGER;
PhoneFileId : File.FileIdType;
RecordId : File.RecordIdType;
WorkBuffer : EntryInfo;
FoundKey : BOOLEAN;
KeyId : File.RecordIdType;
FoundRecord : BOOLEAN;
FirstLetter : String1;
SecondLetter : String1;
BEGIN
AESGraphics.GrafMouseKeyboardState (
MouseLocation.X, MouseLocation.Y, MouseState, KeyboardState );
IF Icon.Find ( WindowResource, MouseLocation, Object ) THEN
(*--- First scan the selector buttons ------------------------*)
Button := 1;
FoundButton := FALSE;
LOOP
IF Object = Selector[Button].ObjectIndex THEN
FoundButton := TRUE;
EXIT;
ELSE
INC (Button);
IF Button > NumberSelectors THEN
EXIT;
END;
END;
END (* LOOP *);
IF FoundButton THEN
IF OpenFile ( PhoneBookFile, LogFileId, PhoneFileId ) THEN
FirstLetter[0] := Selector[Button].Letter[0];
SecondLetter[0] := CHR (ORD (FirstLetter[0]) + 1);
File.Find (
PhoneFileId,
FirstLetter,
"",
ADR (WorkBuffer),
FoundKey,
KeyId,
FoundRecord,
RecordId );
IF NOT FoundKey THEN
File.Find (
PhoneFileId,
SecondLetter,
"",
ADR (WorkBuffer),
FoundKey,
KeyId,
FoundRecord,
RecordId );
END;
File.Close ( PhoneFileId );
ReadPhoneBook ( FoundKey, KeyId, TRUE );
Category := Button;
IF FoundButton AND (NOT FoundKey) THEN
Selector[Category].ObjectPtr^.State :=
Selector[Category].ObjectPtr^.State + {Icon.Selected};
Icon.Display (
Resource.D6PHONE,
Selector[Category].ObjectIndex,
WindowInfo.Borders );
END;
END;
DeselectEntries;
ELSE
ObjectPtr := Icon.GetAddress ( WindowResource, Object );
IF Icon.Disabled IN ObjectPtr^.State THEN
GEMDOS.ConOut ( Bell );
ELSE
(*--- If the object is a button, "flash" it -------------*)
IF ObjectPtr^.Type = GEMAESbase.GraphicButton THEN
ObjectPtr^.State := ObjectPtr^.State + {Icon.Selected};
Icon.Display ( WindowResource, Object, WindowInfo.Borders );
ObjectPtr^.State := ObjectPtr^.State - {Icon.Selected};
END;
IF WindowResource = Resource.D8PHTIME THEN
IF Object = Resource.D8HANGUP THEN
IF DialedEntry <> Null THEN
UpdateLog ( AddTime, "" );
END;
HangUp;
ELSIF Object = Resource.D8CALL THEN
IF DialedEntry = Null THEN
SendName ( Null );
ELSE
UpdateLog ( AddTime, "" );
SendName ( ADR (Name[DialedEntry].Entry.NameText) );
END;
HangUp;
ELSE
GEMDOS.ConOut ( Bell );
END;
ELSE (* WindowResource = Resource.D6PHONE *)
IF Object = Resource.D6NAME1 THEN
ProcessName ( 1, Clicks );
ELSIF Object = Resource.D6NAME2 THEN
ProcessName ( 2, Clicks );
ELSIF Object = Resource.D6NAME3 THEN
ProcessName ( 3, Clicks );
ELSIF Object = Resource.D6NAME4 THEN
ProcessName ( 4, Clicks );
ELSIF Object = Resource.D6NAME5 THEN
ProcessName ( 5, Clicks );
ELSIF Object = Resource.D6NAME6 THEN
ProcessName ( 6, Clicks );
ELSIF Object = Resource.D6NAME7 THEN
ProcessName ( 7, Clicks );
ELSIF Object = Resource.D6NAME8 THEN
ProcessName ( 8, Clicks );
ELSIF Object = Resource.D6TIMCAL THEN
DialedEntry := Null;
DeselectEntries;
TimeCall;
ELSIF Object = Resource.D6DIAL THEN
DialedEntry := SelectedEntry;
UpdateLog ( AddName, Name[DialedEntry].Entry.NameText );
DeselectEntries;
Dial;
ELSIF Object = Resource.D6ADD THEN
DeselectEntries;
AddEntry;
ELSIF Object = Resource.D6DELETE THEN
DeletedEntry := SelectedEntry;
DeselectEntries;
DeleteEntry;
ELSIF Object = Resource.D6CALL THEN
IF SelectedEntry = NoSelectedEntries THEN
SendName ( Null );
ELSE
SendName ( ADR (Name[SelectedEntry].Entry.NameText) );
END;
DeselectEntries;
Icon.Display (
Resource.D6PHONE, Resource.D6CALL, WindowInfo.Borders );
ELSE
GEMDOS.ConOut ( Bell );
END;
END;
END;
END;
ELSE
GEMDOS.ConOut ( Bell );
END;
AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
END ProcessButtonEvent;
(********************************************************************)
PROCEDURE ProcessKeyboardEvent ( Key : INTEGER;
ModifierKey : INTEGER );
BEGIN
GEMDOS.ConOut ( Bell );
END ProcessKeyboardEvent;
BEGIN
WindowAllocated := FALSE;
WindowResource := Resource.D6PHONE;
SelectedEntry := NoSelectedEntries;
VirginTool := TRUE;
PreviousTime := 0;
END PhoneBook.